Skip to content

Conversation

Vipul-Cariappa
Copy link
Collaborator

@Vipul-Cariappa Vipul-Cariappa commented Aug 11, 2025

Big changes in this PR. Some parts of the explanation might be like a conversation.

Mutex lock per interpreter.

Question: Do we need a per-interpreter lock?
Answer: Yes. Ideally, that would improve the performance in multi-threaded cases.

Question: Does the InterOp API fully support dispatching queries (some kind of lookup) or compiling code across multiple interpreters at the same time?
Answer: Actually, (I guess) No. Our API only supports stack-like access of multiple interpreters.
Example code that will not work:

auto interpreter_1 = Cpp::CreateInterpreter();
Cpp::Compile(R"(
void f() {}
)");
auto f = Cpp::GetNamed("f");

auto interpreter_2 = Cpp::CreateInterpreter();
Cpp::Compile(R"(
void ff() {}
)");

auto ff = Cpp::GetNamed("ff");

auto f_callable = Cpp::MakeFunctionCallable(f); // This fails because:
// MakeFunctionCallable uses the interpreter instance 2 at line
// https://github.com/compiler-research/CppInterOp/blob/dba60ff3d829551b1c86128593ca817af78d67dc/lib/CppInterOp/CppInterOp.cpp#L3148-L3150

But you can make the above example work, if the user rotates the sInterpreters.
Example:

auto interpreter_1 = Cpp::CreateInterpreter();
Cpp::Compile(R"(
void f() {}
)");
auto f = Cpp::GetNamed("f");

auto interpreter_2 = Cpp::CreateInterpreter();
Cpp::Compile(R"(
void ff() {}
)");

auto ff = Cpp::GetNamed("ff");

Cpp::ActivateInterpreter(interpreter_1); // look at https://github.com/compiler-research/CppInterOp/blob/dba60ff3d829551b1c86128593ca817af78d67dc/lib/CppInterOp/CppInterOp.cpp#L3273-L3287
auto f_callable = Cpp::MakeFunctionCallable(f);

Question: Ok. So is there a way for InterOp is maintain the rotation thing?
Answer: Would not be a easy thing to achieve. From my initial view on the matter, it might be possible. But a more important question; Should we support such usecases?

Question: Ok. So given the limitation of using multiple interpreter but only as a stack-access. Do we need a mutex lock per interpreter?
Answer: No, the user can only access the top most interpreter at a time. We don't need a mutex per interpreter. (Let me know if my reasoning is wrong somewhere)

Testing this by running in parallel

gtest does not support running in parallel (I could not find anything with my google search). But there is this project, gtest-parallel, that can split the tasks into separate isolated processes. But that is not what we want. We want to split the tests to run in parallel threads that share the same interpreter instance.

Code recovery RAII

@vgvassilev, I need some pointers on incorporating the codegen error recovery RAII. I don't think we should combine the two into the same class, but let me know your opinion. And how should I go about doing it?

@Vipul-Cariappa Vipul-Cariappa marked this pull request as draft August 11, 2025 12:51
Copy link

codecov bot commented Aug 11, 2025

Codecov Report

❌ Patch coverage is 97.22222% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.46%. Comparing base (33a3e7e) to head (d55415e).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
lib/CppInterOp/CppInterOp.cpp 97.22% 10 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #698      +/-   ##
==========================================
+ Coverage   79.83%   81.46%   +1.62%     
==========================================
  Files           9        9              
  Lines        3962     4213     +251     
==========================================
+ Hits         3163     3432     +269     
+ Misses        799      781      -18     
Files with missing lines Coverage Δ
include/CppInterOp/CppInterOp.h 95.55% <ø> (ø)
lib/CppInterOp/CppInterOpInterpreter.h 88.02% <ø> (-0.53%) ⬇️
lib/CppInterOp/CppInterOp.cpp 89.60% <97.22%> (+1.56%) ⬆️

... and 2 files with indirect coverage changes

Files with missing lines Coverage Δ
include/CppInterOp/CppInterOp.h 95.55% <ø> (ø)
lib/CppInterOp/CppInterOpInterpreter.h 88.02% <ø> (-0.53%) ⬇️
lib/CppInterOp/CppInterOp.cpp 89.60% <97.22%> (+1.56%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 10 out of 13. Check the log or trigger a new build to see more.

@Vipul-Cariappa Vipul-Cariappa marked this pull request as ready for review August 11, 2025 13:29
@@ -224,11 +301,18 @@ std::string Demangle(const std::string& mangled_name) {
return demangle;
}

void EnableDebugOutput(bool value /* =true*/) { llvm::DebugFlag = value; }
void EnableDebugOutput(bool value /* =true*/) {
LOCK(getInterpInfo());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a different mental model for this. I was thinking that we can have a StateMutatingSection RAII object which in turn has a mutex-based locking (if multithreading was enabled) and a 'PushTransactionRAII` (for pch/modules). The object should take a parameter if the change is in clang AST which might trigger a derserialiazation or llvm-only. In the latter case we can skip pushing a transaction.

There will be cases where we need one of the two concepts and not both. We need to design a flexible solution addressing these needs without having to introduce both concepts at the same time when they are not needed.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 10 out of 19. Check the log or trigger a new build to see more.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@mcbarton
Copy link
Collaborator

A note for this PR. The Emscripten build of CppInterOp doesn't currently support threads

-DLLVM_ENABLE_THREADS=OFF \

It is possible to turns threads on, and modify CppInterOp, so that it builds with threads. I did this locally yesterday (I did this in the past before we had tests). The tests can run, but several of our currently passing tests fail with threads enabled. We also get a warning about shared memory for the passing tests. I can put a PR showing my current progress, but I don't know how far I would get enabling past what I already have since shared library with pthreads is labelled as experimental on Emscripten, so we might be trying to fight possible bugs in Emscripten.

@mcbarton
Copy link
Collaborator

Codecov Report

❌ Patch coverage is 94.02985% with 12 lines in your changes missing coverage. Please review. ✅ Project coverage is 80.34%. Comparing base (6cf1c06) to head (e6a33f8).
Files with missing lines Patch % Lines
lib/CppInterOp/CppInterOp.cpp 94.02% 12 Missing ⚠️
Additional details and impacted files

🚀 New features to boost your workflow:

@Vipul-Cariappa can you add tests so that all lines of your patch are covered by tests?

@Vipul-Cariappa Vipul-Cariappa force-pushed the dev/lock branch 3 times, most recently from 57caa27 to 97bd9b8 Compare August 22, 2025 11:34
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@Vipul-Cariappa Vipul-Cariappa changed the title add mutex per interpreter per thread [Thread-Safety] Add Mutex per Interpreter Aug 27, 2025
@mcbarton
Copy link
Collaborator

mcbarton commented Sep 5, 2025

Codecov Report

❌ Patch coverage is 89.45869% with 37 lines in your changes missing coverage. Please review. ✅ Project coverage is 80.29%. Comparing base (d85eec0) to head (3cf9aec).
Files with missing lines Patch % Lines
lib/CppInterOp/CppInterOp.cpp 89.45% 37 Missing ⚠️
Additional details and impacted files

🚀 New features to boost your workflow:

@vgvassilev Just over 10% over this PR is not covered by tests according to this message. Maybe @Vipul-Cariappa could add more tests to increase this coverage too before this goes in?

@vgvassilev
Copy link
Contributor

Codecov Report

❌ Patch coverage is 89.45869% with 37 lines in your changes missing coverage. Please review. ✅ Project coverage is 80.29%. Comparing base (d85eec0) to head (3cf9aec).
Files with missing lines Patch % Lines
lib/CppInterOp/CppInterOp.cpp 89.45% 37 Missing ⚠️
Additional details and impacted files
🚀 New features to boost your workflow:

@vgvassilev Just over 10% over this PR is not covered by tests according to this message. Maybe @Vipul-Cariappa could add more tests to increase this coverage too before this goes in?

Good point. I’d guess most of the uncovered lines are due to preexisting lack of coverage but would be nice to improve the coverage where possible.

@Vipul-Cariappa Vipul-Cariappa force-pushed the dev/lock branch 2 times, most recently from 4feb220 to 1e473ce Compare September 5, 2025 15:14
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@Vipul-Cariappa
Copy link
Collaborator Author

Hi @mcbarton, I am using threads with that new test case I have written. And that test case is failing on WASM. I can just skip it. But was thinking if this can potentially enable it? Any comments or thoughts?


@vgvassilev, @mcbarton, The test I have written covers some more lines, but the effort to cover all of the missing lines isn't worth it. I advise we go forward with this. We can gradually cover more lines.

@vgvassilev
Copy link
Contributor

Hi @mcbarton, I am using threads with that new test case I have written. And that test case is failing on WASM. I can just skip it. But was thinking if this can potentially enable it? Any comments or thoughts?

@vgvassilev, @mcbarton, The test I have written covers some more lines, but the effort to cover all of the missing lines isn't worth it. I advise we go forward with this. We can gradually cover more lines.

Disabling the wasm test should be fine.

I looked at the missing coverage. Yes, some are not caused by this PR but most are really trivial to add tests for and some are just dead code.

@mcbarton
Copy link
Collaborator

mcbarton commented Sep 8, 2025

@Vipul-Cariappa Disabling it is the way to go. We do not currently support threads for the wasm build, and enabling them will quite an involved project from my investigations so far. My progress so far managed to get the tests to run with threads, but we end up with tests failing which currently pass. Also using threads with an Emscripten shared library is currently labelled as experimental.

@Vipul-Cariappa
Copy link
Collaborator Author

Skipped the test in WASM.
@vgvassilev, I guess this can be approved now. To be merged once the CI is green.

@mcbarton
Copy link
Collaborator

mcbarton commented Sep 8, 2025

Skipped the test in WASM. @vgvassilev, I guess this can be approved now. To be merged once the CI is green.

I don't know how many commits this is behind main, but it needs rebasing according to the Github interface so we can ci can test your changes with the latest changes on main.

@vgvassilev
Copy link
Contributor

Skipped the test in WASM. @vgvassilev, I guess this can be approved now. To be merged once the CI is green.

You don’t want to spend 30 mins writing these tests to make our coverage happy?

@mcbarton
Copy link
Collaborator

mcbarton commented Sep 8, 2025

The tests which use printf (or anything which tries to write to standard output) will cause the ci to fail on Windows. This is a known issue and these tests will need to be skipped on Windows.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

EXPECT_EQ(members.size(), 0);

EXPECT_FALSE(
Cpp::InsertOrReplaceJitSymbol("printf", (uint64_t)&printf_jit, I));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]

        Cpp::InsertOrReplaceJitSymbol("printf", (uint64_t)&printf_jit, I));
                                                ^

EXPECT_EQ(members.size(), 0);

EXPECT_FALSE(
Cpp::InsertOrReplaceJitSymbol("printf", (uint64_t)&printf_jit, I));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "uint64_t" is directly included [misc-include-cleaner]

        Cpp::InsertOrReplaceJitSymbol("printf", (uint64_t)&printf_jit, I));
                                                 ^

EXPECT_EQ(f_callable.getKind(), Cpp::JitCall::Kind::kGenericCall);

EXPECT_FALSE(
Cpp::TakeInterpreter((TInterp_t)1)); // try to take ownership of an
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]

        Cpp::TakeInterpreter((TInterp_t)1)); // try to take ownership of an
                             ^

EXPECT_NE(std::find(includes.begin(), includes.end(), "/non/existent/"),
std::end(includes));

EXPECT_TRUE(Cpp::InsertOrReplaceJitSymbol("non_existent", (uint64_t)&f, I));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]

    EXPECT_TRUE(Cpp::InsertOrReplaceJitSymbol("non_existent", (uint64_t)&f, I));
                                                              ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

EXPECT_TRUE(Cpp::GetInterpreter()) << "External Interpreter not set";
Cpp::UseExternalInterpreter(ExtInterp);
EXPECT_EQ(ExtInterp, Cpp::GetInterpreter());
EXPECT_EQ(ExtInterp, Cpp::TakeInterpreter(ExtInterp));

#ifndef CPPINTEROP_USE_CLING
I.release();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: Method called on moved-from object 'I' [clang-analyzer-cplusplus.Move]

  I.release();
  ^
Additional context

unittests/CppInterOp/InterpreterTest.cpp:322: Assuming the condition is false

if (llvm::sys::RunningOnValgrind())
    ^

unittests/CppInterOp/InterpreterTest.cpp:322: Taking false branch

if (llvm::sys::RunningOnValgrind())
^

unittests/CppInterOp/InterpreterTest.cpp:338: Object 'I' is moved

  auto CPPI = Cpp::Interpreter(std::move(I));
                               ^

unittests/CppInterOp/InterpreterTest.cpp:354: Control jumps to 'case 0:' at line 355

  EXPECT_NE(ExtInterp, nullptr);
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1886: expanded from macro 'EXPECT_NE'

  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:77: expanded from macro 'GTEST_ASSERT_'

  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                 \
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/internal/gtest-port.h:727: expanded from macro 'GTEST_AMBIGUOUS_ELSE_BLOCKER_'

  switch (0)                          \
  ^

unittests/CppInterOp/InterpreterTest.cpp:354: Assuming the condition is true

  EXPECT_NE(ExtInterp, nullptr);
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1886: expanded from macro 'EXPECT_NE'

  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
                                       ^

unittests/CppInterOp/InterpreterTest.cpp:354: Taking true branch

  EXPECT_NE(ExtInterp, nullptr);
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1886: expanded from macro 'EXPECT_NE'

  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
  ^

unittests/CppInterOp/InterpreterTest.cpp:357: Control jumps to 'case 0:' at line 358

  EXPECT_EQ(ExtInterp, Cpp::GetInterpreter());
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:77: expanded from macro 'GTEST_ASSERT_'

  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                 \
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/internal/gtest-port.h:727: expanded from macro 'GTEST_AMBIGUOUS_ELSE_BLOCKER_'

  switch (0)                          \
  ^

unittests/CppInterOp/InterpreterTest.cpp:357: Assuming the condition is true

  EXPECT_EQ(ExtInterp, Cpp::GetInterpreter());
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
                                       ^

unittests/CppInterOp/InterpreterTest.cpp:357: Taking true branch

  EXPECT_EQ(ExtInterp, Cpp::GetInterpreter());
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
  ^

unittests/CppInterOp/InterpreterTest.cpp:358: Control jumps to 'case 0:' at line 359

  EXPECT_EQ(ExtInterp, Cpp::TakeInterpreter(ExtInterp));
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:77: expanded from macro 'GTEST_ASSERT_'

  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                 \
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/internal/gtest-port.h:727: expanded from macro 'GTEST_AMBIGUOUS_ELSE_BLOCKER_'

  switch (0)                          \
  ^

unittests/CppInterOp/InterpreterTest.cpp:358: Assuming the condition is true

  EXPECT_EQ(ExtInterp, Cpp::TakeInterpreter(ExtInterp));
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
                                       ^

unittests/CppInterOp/InterpreterTest.cpp:358: Taking true branch

  EXPECT_EQ(ExtInterp, Cpp::TakeInterpreter(ExtInterp));
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest.h:1884: expanded from macro 'EXPECT_EQ'

  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:143: expanded from macro 'EXPECT_PRED_FORMAT2'

  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:133: expanded from macro 'GTEST_PRED_FORMAT2_'

  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
  ^

build/unittests/googletest-prefix/src/googletest/googletest/include/gtest/gtest_pred_impl.h:78: expanded from macro 'GTEST_ASSERT_'

  if (const ::testing::AssertionResult gtest_ar = (expression)) \
  ^

unittests/CppInterOp/InterpreterTest.cpp:361: Method called on moved-from object 'I'

  I.release();
  ^

@@ -0,0 +1,11 @@
#ifndef UNITTESTS_CPPINTEROP_TESTSHAREDLIB_TESTSHAREDLIB2_H
#define UNITTESTS_CPPINTEROP_TESTSHAREDLIB_TESTSHAREDLIB2_H
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: header guard does not follow preferred style [llvm-header-guard]

Suggested change
#define UNITTESTS_CPPINTEROP_TESTSHAREDLIB_TESTSHAREDLIB2_H
#ifndef GITHUB_WORKSPACE_UNITTESTS_CPPINTEROP_TESTSHAREDLIB2_TESTSHAREDLIB_H
#define GITHUB_WORKSPACE_UNITTESTS_CPPINTEROP_TESTSHAREDLIB2_TESTSHAREDLIB_H

unittests/CppInterOp/TestSharedLib2/TestSharedLib.h:10:

- #endif // UNITTESTS_CPPINTEROP_TESTSHAREDLIB_TESTSHAREDLIB2_H
+ #endif // GITHUB_WORKSPACE_UNITTESTS_CPPINTEROP_TESTSHAREDLIB2_TESTSHAREDLIB_H

Copy link
Contributor

@vgvassilev vgvassilev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

LGTM, modulo the comments. Consider squashing all into one commit or condensing a good atomic minimal set of commits...

}

std::string ObjToString(const char* type, void* obj) {
return getInterp().toString(type, obj);
LOCK(getInterpInfo(NULLPTR)); // FIXME: not enough information to lock the
// corrent interpreter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// corrent interpreter
// current interpreter

Please move the comment above the line.

    Have a mutex for each interpreter instance create.
    Only use the lock at writes to the AST.

Use hashmap to identify Sema & AST from individual Decl

    We need to identify which interpreter a Decl belongs to, when using multiple interpreter.
    We do it by checking which `clang::ASTContext` the `clang::Decl` belongs
    We maintain a map: `clang::ASTContext -> Cpp::InterpreterInfo`. Using this map, we identify the correct interpreter.

    Note that the mutex is stored in the InterpreterInfo class.

    There are 2 usecases for this:
    1. We can now lock the correct interpreter making it thread safe.
    2. User of `libCppInterOp` need not set the correct active interpreter using `Cpp::ActivateInterpreter`,
       this information can be retrived using the map.
Pops interpreter without destroying it.
Destruction to be handled by the caller.
This is to be used along with UserExternalInterpreter, where libCppInterOp is not owning the interpreter instance.
Functions like Declare compile code into the top-most interpreter in the stack.
If the user wants to compile the code to some other interpreter instance,
user can use the `TInterp_t` argument to specify the interpreter.

This is also required to lock the correct interpreter instance.
If `TInterp_t` is null, we assume the correct interpreter to lock is the top of the stack.
This assumption might be wrong at some cases.
Add test to run things in parallel
Add documentation for developers
@Vipul-Cariappa Vipul-Cariappa merged commit c42c907 into compiler-research:main Sep 10, 2025
62 of 63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants